from QQLoginTool.QQtool import OAuthQQ
from django.conf import settings
from rest_framework import status
from rest_framework.response import Response
from rest_framework.views import APIView
from rest_framework_jwt.settings import api_settings

from oauth.models import OAuthQQUser
from oauth.serializers import QQuserSerializer

from oauth.utils import generate_encrypted_openid

'''
1. 显示QQ登录界面（获取QQ登录的url地址接口）
2. 准备回调界面，获取code参数
3. 实现QQ认证接口
	（1）根据 code 获取 access_token
	（2）根据 access_token 获取openid
	（3）根据 openid, 从映射表查询美多用户
		- 如果能查询到美多用户，则生成并响应jwt, user_id, username， 完成QQ登录流程
		- 如果能查询不到美多用户， 则返回openid, 等待用户后续的绑定操作
4. 绑定openid和美多用户
'''


# 提供QQ登陆的网址
class QQURLView(APIView):

    # 提供QQ登陆页面的网址
    def get(self,request):

        # next表示登陆成功后需要进入的页面
        next = request.query_params.get('next')

        if not next:
            next = '/'  # 首页
        oauth = OAuthQQ(client_id=settings.QQ_CLIENT_ID,
                        client_secret=settings.QQ_CLIENT_SECRET,
                        redirect_uri=settings.QQ_REDIRECT_URI,
                        state=next)
        login_url = oauth.get_qq_url()
        return Response({'login_url': login_url})

# 用户扫码登陆后的操作 对codes参数处理拿到openid 和数据库对比实现登陆
# url(r'^qq/user/$', views.QQUserView.as_view()),


class QQUserView(APIView):
    """用户扫码登录的回调处理"""
    def get(self, request):

        # 1. 获取code对象并提取codes里面的参数
        code = request.query_params.get('code')
        if not code:
            return Response({'message':'缺少code'}, status=status.HTTP_400_BAD_REQUEST)

        # 创建工具对象 (都是settings中的配置文件)
        oauth = OAuthQQ(client_id=settings.QQ_CLIENT_ID,
                        client_secret=settings.QQ_CLIENT_SECRET,
                        redirect_uri=settings.QQ_REDIRECT_URI)
        try:
            # 使用code向QQ服务器请求 access_token
            access_token = oauth.get_access_token(code)

            # 使用access_token向qq服务器获取openid
            openid = oauth.get_open_id(access_token)

        except:
            return Response({'message':'获取access_token失败'}, status=status.HTTP_400_BAD_REQUEST)

        # 使用openid在数据库中进行关联查询 判断该QQ用户是否在商城注册过
        try:
            oauth_user = OAuthQQUser.objects.get(openid=openid)
        except OAuthQQUser.DoesNotExist:
            # 如果openid没有绑定过美多商城用户， 则需要进行绑定
            # 在这里将openid返回给前端，绑定时再传递服务器  (加密签名后再响应给端)
            # 调用序列化器进行对openid加密处理 最后返回给前端
            openid = generate_encrypted_openid(openid)
            return Response({'openid': openid})

        else:
            # 到此表示登陆成功， 如果openid 已绑定美多商城用户 就直接生成jwt 并返回给浏览器
            jwt_payload_handler = api_settings.JWT_PAYLOAD_HANDLER
            jwt_encode_handler = api_settings.JWT_ENCODE_HANDLER

            # 获取oauth_user 关联的user
            user = oauth_user.user
            payload = jwt_payload_handler(user)
            token = jwt_encode_handler(payload)   # 生成jwt

            # 通过response将jwt返回给浏览器
            response = Response({
                'token':token,
                'user_id':user.id,
                'username':user.username
                })

            return response

    # 用户绑定页面 需要提交数据  需要校验数据
    def post(self, request):
        '''
        根据前端绑定页面分析需要校验并返回4个参数
            参数	类型	是否必须	说明
            mobile	str	是	手机号
            password	str	是	密码
            sms_code	str	是	短信验证码
            openid	str	是	经过了签名(加密)处理的openid

        绑定openid和美多用户
        '''

        # 创建序列化器对象
        serializer = QQuserSerializer(data=request.data)

        # 校验请求参数
        serializer.is_valid(raise_exception=True)

        # 绑定openid 和美多用户（添加一条数据）
        user = serializer.save()

        # 到此步为止  绑定成功 生成jwt并响应 完成登陆
        jwt_payload_handler = api_settings.JWT_PAYLOAD_HANDLER
        jwt_encode_handler = api_settings.JWT_ENCODE_HANDLER
        payload = jwt_payload_handler(user)
        token = jwt_encode_handler(payload)

        # 后端准备相应参数返回给前端
        Response({
            'token':token,
            'user_id':user.id,
            'username':user.name

        })

        return request









